package com.zhuqi.bloomfilter;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


/**
 * @author : ZhuQi
 * @version : 时间:2022/1/7 9:21 版本: 1.0.0
 * 使用布隆过滤器过滤缓存
 *
 * 模拟场景:查询用户健康码
 */
//@Component
@Slf4j
//@Aspect
public class BloomFilter {

    final String point = "@annotation(com.zhuqi.bloomfilter.BloomFilterCode)";

//    @Autowired
    private RedissonClient redissonClient;

    /**
     * 过滤器key
     */
    public static final String CODE_KEY_PREFIX = "USER_CODE_BLOOM_FILTER";

    /**
     * 布隆过滤器
     */
    private  RBloomFilter<String> bloomFilter = null;

    /**
     * 初始化过滤器
     */
//    @PostConstruct
    public void init() {
        bloomFilter = redissonClient.getBloomFilter(CODE_KEY_PREFIX, StringCodec.INSTANCE);
        bloomFilter.tryInit(1000L, 0.03D);
        createData();
    }

//    @Around(value = point)
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("进入布隆过滤器校验");

        String arg = (String) joinPoint.getArgs()[0];
        if (!bloomFilter.contains(arg)) {
            log.info("过滤器没有识别到该id对应的数据，该ID可能为而已攻击");
            return "没有这个用户，没有二维码";
        }
        Object proceed = joinPoint.proceed(joinPoint.getArgs());
        return proceed;
    }

    /**
     * 初始化用户数据
     */
    public void createData(){
        bloomFilter.add("1");
        bloomFilter.add("2");
        bloomFilter.add("3");
        bloomFilter.add("4");
        bloomFilter.add("5");
    }
}
